package fr.emse.tatiana.analysis.annotation;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Observable;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.ILazyContentProvider;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableColorProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.Table;
import org.w3c.dom.Node;

import fr.emse.tatiana.display.BadDisplayFile;
import fr.emse.tatiana.display.DisplayFileReader;
import fr.emse.tatiana.display.DisplayFileWriter;
import fr.emse.tatiana.display.Ut;
import fr.emse.tatiana.filter.FilterParameter;
import fr.emse.tatiana.replayable.Anchor;
import fr.emse.tatiana.replayable.analysis.AbstractAnalysis;
import fr.emse.tatiana.replayable.analysis.AnalysisEvent;
import fr.emse.tatiana.replayable.analysis.AnalysisEventListener;
import fr.emse.tatiana.replayable.analysis.IAnalysis;

public class AnnotationAnalysis extends AbstractAnalysis implements ICellModifier {
	
	public final static String DISPLAY_TYPE = "fr.emse.tatiana.analysis";
	

	public AnnotationAnalysis(String name, IProject p) {
		super(name,p);
	}



	public AnnotationAnalysis(IFile file) throws BadDisplayFile {
		super(file);
	}

	@Override
	protected void doInit() {
		// do nothing
		
	}

	protected void parseFile(DisplayFileReader reader) throws BadDisplayFile {
		if (!DISPLAY_TYPE.equals(reader.getType())) {
			throw new BadDisplayFile(BadDisplayFile.WRONGFILETYPE +" expected:"+DISPLAY_TYPE);
		}
		for (boolean notdone = reader.selectFirstItem();notdone;notdone = reader.selectNextItem()) {
			Anchor anchor = reader.getAnchorValue("target-anchor", BadDisplayFile.MISSINGFIELD);
			String comment = reader.getStringValue("comment", BadDisplayFile.MISSINGFIELD);
			values.put(anchor,comment);
		}
		saved = true;
		fireAnalysisEvent(new AnalysisEvent(this));
	}

	protected boolean saveToAnalysisFile(IFile file) {
		DisplayFileWriter writer = new DisplayFileWriter(file.getLocation().toString(),DISPLAY_TYPE);

		for (Anchor anchor : values.keySet()) {
			Object annotation = values.get(anchor);
			if (annotation != null && annotation != doGetNullValue()) {
				writer.newItem();
				writer.newInfoFromString("target-anchor", anchor.toString());
				writer.newInfo("comment", "", doGetStringValue(annotation));
			}
		}
		writer.close();
		saved = true;
		return true;
	}
	
	/* (non-Javadoc)
	 * @see fr.emse.tatiana.replayable.analysis.IAnalysis#doSave()
	 */


	public IStructuredContentProvider getContentProvider() {
		return new AnalysisContentProvider();
	}

	public ICellModifier getCellModifier() {
		return this;
	}

	public IBaseLabelProvider getLabelProvider() {
		return new AnalysisLabelProvider();
	}

	public class AnalysisContentProvider implements IStructuredContentProvider, AnalysisEventListener {

		protected Viewer v;
		protected IAnalysis a;

		public Object[] getElements(Object inputElement) {
			Set<Object> set = new HashSet<Object>();
			set.addAll(values.values());
			return values.values().toArray();
		}

		public void dispose() {
			if (a!=null)
				a.removeAnalysisEventListener(this);
		}

		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
			if (oldInput!=null)
				((IAnalysis)oldInput).removeAnalysisEventListener(this);
			if (newInput!=null) {
				a = (IAnalysis) newInput;
				a.addAnalysisEventListener(this);
			}
			v = viewer;
		}

		public void analysisEventOccurred(AnalysisEvent evt) {
			if (v!=null) { 
				v.refresh();
			}

		}
	}

	public class AnalysisLabelProvider extends LabelProvider implements ITableLabelProvider {
		
		public Image getColumnImage(Object element, int columnIndex) {
			return null;
		}
		
		public String getColumnText(Object element, int columnIndex) {
			return doGetStringValue(element);
		}
	}
	
	
	public boolean canModify(Object element, String property) {
		return false;
	}
	
	public Object getValue(Object element, String property) {
		return element.toString();
	}
	
	public void modify(Object element, String property, Object value) {
		// do nothing
	}

	public String[] getColumnNames() {
		return new String[]{"Annotations"};
	}

	public CellEditor[] getCellEditors(Composite parent) {
		return new CellEditor[]{null};
	}
	
	
}